# 异常值检测
# 使用算法：Tukey's Test
# 该算法是用四分位数是自动识别出可能的异常值的。将数列从小到大排列，取下四分位数Q1和上四分位数Q3。用公式估计出该数列的最大值和最小值
# 1.数列中小于Q1-3*(Q3-Q1)和大于Q3+3*(Q3-Q1)的值属于重度异常值；
# 2.数列中介于Q1-1.5*(Q3-Q1)和Q1-3*(Q3-Q1)，以及介于Q1+1.5*(Q3-Q1)和Q1+3*(Q3-Q1)的值属于中度异常值；
# 3.其他为正常值
# K一般情况下取1.5，计算出的是中度异常的范围，K=3计算出的是极度异常的范围。

import numpy as np
import stats as sts
import seaborn as sns
import matplotlib.pyplot as plt
import xlrd  #读Excel数据用

file_location = "D:\服创\数数数学学学建建建模模模\鸢尾花X数据.xlsx"
data = xlrd.open_workbook(file_location) #	data是Excel里的数据
sheet = data.sheet_by_index(0)  #读取到第一张表格
list = [sheet.cell_value(r,1) for r in range(1,sheet.nrows)]   # 读取到第1列的所有值
print(list)

# 求四分位数
print('下四分位数：', sts.quantile(list,p=0.25))
print('上四分位数：', sts.quantile(list,p=0.75))
q1 = sts.quantile(list,p=0.25)
q3 = sts.quantile(list,p=0.75)

#k=1.5  中度异常
k1 = 1.5
g_min_m = q1-k1*(q3-q1)
g_max_m = q3+k1*(q3-q1)

#k=3 重度异常
k2 = 3
g_min_b = q1-k2*(q3-q1)
g_max_b = q3+k2*(q3-q1)

# g_min_b, g_min_m, g_max_m, g_max_b
print(g_min_b, g_min_m, g_max_m, g_max_b)
for i in list:
    if i<g_min_b or i>g_max_b:
        print('重度异常值：', i)
    elif i>g_min_b and i<g_min_m:
         print('中度异常值：', i)
    elif i>g_max_m and i<g_max_b:
         print('中度异常值：', i)



outpoints = sns.boxplot(data=list)
plt.show()